home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 August (Alt) / CHIP 2005-08.1.iso / program / guvenlik / syslinux-3.07.exe / memdisk / memdisk.asm < prev    next >
Encoding:
Assembly Source File  |  2004-12-29  |  15.4 KB  |  747 lines

  1. ; -*- fundamental -*- (asm-mode sucks)
  2. ; $Id: memdisk.asm,v 1.26 2004/12/29 19:34:13 hpa Exp $
  3. ; ****************************************************************************
  4. ;
  5. ;  memdisk.asm
  6. ;
  7. ;  A program to emulate an INT 13h disk BIOS from a "disk" in extended
  8. ;  memory.
  9. ;
  10. ;   Copyright (C) 2001-2004  H. Peter Anvin
  11. ;
  12. ;  This program is free software; you can redistribute it and/or modify
  13. ;  it under the terms of the GNU General Public License as published by
  14. ;  the Free Software Foundation, Inc., 53 Temple Place Ste 330,
  15. ;  Boston MA 02111-1307, USA; either version 2 of the License, or
  16. ;  (at your option) any later version; incorporated herein by reference.
  17. ; ****************************************************************************
  18.  
  19. %ifndef DEPEND
  20. %include    "../version.gen"
  21. %endif
  22.  
  23. ; %define DEBUG_TRACERS            ; Uncomment to get debugging tracers
  24.  
  25. %ifdef DEBUG_TRACERS
  26.  
  27. %macro TRACER    1
  28.     call debug_tracer
  29.     db %1
  30. %endmacro
  31.  
  32. %else    ; DEBUG_TRACERS
  33.  
  34. %macro    TRACER    1
  35. %endmacro
  36.  
  37. %endif    ; DEBUG_TRACERS
  38.  
  39.         org 0h
  40.  
  41. %define SECTORSIZE_LG2    9        ; log2(sector size)
  42. %define    SECTORSIZE    (1 << SECTORSIZE_LG2)
  43.  
  44.         ; Parameter registers definition; this is the definition
  45.         ; of the stack frame.
  46. %define        P_DS        word [bp+34]
  47. %define        P_ES        word [bp+32]
  48. %define        P_EAX        dword [bp+28]
  49. %define        P_HAX        word [bp+30]
  50. %define        P_AX        word [bp+28]
  51. %define        P_AL        byte [bp+28]
  52. %define        P_AH        byte [bp+29]
  53. %define        P_ECX        dword [bp+24]
  54. %define        P_HCX        word [bp+26]
  55. %define        P_CX        word [bp+24]
  56. %define        P_CL        byte [bp+24]
  57. %define        P_CH        byte [bp+25]
  58. %define        P_EDX        dword [bp+20]
  59. %define        P_HDX        word [bp+22]
  60. %define        P_DX        word [bp+20]
  61. %define        P_DL        byte [bp+20]
  62. %define        P_DH        byte [bp+21]
  63. %define        P_EBX        dword [bp+16]
  64. %define        P_HBX        word [bp+18]
  65. %define        P_HBXL        byte [bp+18]
  66. %define        P_BX        word [bp+16]
  67. %define        P_BL        byte [bp+16]
  68. %define        P_BH        byte [bp+17]
  69. %define        P_EBP        dword [bp+8]
  70. %define        P_BP        word [bp+8]
  71. %define        P_ESI        dword [bp+4]
  72. %define        P_SI        word [bp+4]
  73. %define        P_EDI        dword [bp]
  74. %define        P_DI        word [bp]
  75.  
  76.         section .text
  77.         ; These pointers are used by the installer and
  78.         ; must be first in the binary
  79. Pointers:    dw Int13Start
  80.         dw Int15Start
  81.         dw PatchArea
  82.         dw TotalSize
  83.  
  84. Int13Start:
  85.         ; Swap stack
  86.         mov [cs:Stack],esp
  87.         mov [cs:SavedAX],ax
  88.         mov ax,ss
  89.         mov [cs:Stack+4],ax
  90.         mov ax,cs
  91.         mov ss,ax
  92.         mov sp,[cs:MyStack]
  93.  
  94.         ; See if DL points to our class of device (FD, HD)
  95.         push dx
  96.         push dx
  97.         xor dl,[cs:DriveNo]
  98.         pop dx
  99.         js .nomatch        ; If SF=0, we have a class match here
  100.         jz .our_drive        ; If ZF=1, we have an exact match
  101.         cmp dl,[cs:DriveNo]
  102.         jb .nomatch        ; Drive < Our drive
  103.         dec dl            ; Drive > Our drive, adjust drive #
  104. .nomatch:
  105.         mov ax,[cs:SavedAX]
  106.         pushf
  107.         call far [cs:OldInt13]
  108.         pushf
  109.         push bp
  110.         mov bp,sp
  111.         cmp byte [cs:SavedAX+1],08h
  112.         je .norestoredl
  113.         cmp byte [cs:SavedAX+1],15h
  114.         jne .restoredl
  115.         test byte [bp+4],80h    ; Hard disk?
  116.         jnz .norestoredl
  117. .restoredl:
  118.         mov dl,[bp+4]
  119. .norestoredl:
  120.         push ax
  121.         push ebx
  122.         push ds
  123.         mov ax,[bp+2]        ; Flags
  124.         lds ebx,[cs:Stack]
  125.         mov [bx+4],al        ; Arithmetric flags
  126.         pop ds
  127.         pop ebx
  128.         pop ax
  129.         pop bp
  130.         lss esp,[cs:Stack]
  131.         iret
  132.  
  133. .our_drive:
  134.         ; Set up standard entry frame
  135.         push ds
  136.         push es
  137.         mov ds,ax
  138.         mov es,ax
  139.         mov ax,[SavedAX]
  140.         pushad
  141.         mov bp,sp        ; Point BP to the entry stack frame
  142.         TRACER 'F'
  143.         ; Note: AH == P_AH here
  144.         cmp ah,Int13FuncsMax
  145.         jae Invalid_jump
  146.         xor al,al        ; AL = 0 is standard entry condition
  147.         mov di,ax
  148.         shr di,7        ; Convert AH to an offset in DI
  149.         call [Int13Funcs+di]
  150.  
  151. Done:        ; Standard routine for return
  152.         mov P_AX,ax
  153. DoneWeird:
  154.         TRACER 'D'
  155.         xor bx,bx
  156.         mov es,bx
  157.         mov bx,[StatusPtr]
  158.         mov [es:bx],ah        ; Save status
  159.         and ah,ah
  160.  
  161.         lds ebx,[Stack]
  162.         ; This sets the low byte (the arithmetric flags) of the
  163.         ; FLAGS on stack to either 00h (no flags) or 01h (CF)
  164.         ; depending on if AH was zero or not.
  165.         setnz [bx+4]        ; Set CF iff error
  166.         popad
  167.         pop es
  168.         pop ds
  169.         lss esp,[cs:Stack]
  170.         iret
  171.  
  172. Reset:
  173.         ; Reset affects multiple drives, so we need to pass it on
  174.         TRACER 'R'
  175.         test dl,dl        ; Always pass it on if we are resetting HD
  176.         js .pass_on        ; Bit 7 set
  177.         ; Some BIOSes get very unhappy if we pass a reset floppy
  178.         ; command to them and don't actually have any floppies.
  179.         ; This is a bug, but we have to deal with it nontheless.
  180.         ; Therefore, if we are the *ONLY* floppy drive, and the
  181.         ; user didn't request HD reset, then just drop the command.
  182.         xor ax,ax        ; Bottom of memory
  183.         mov es,ax
  184.         ; BIOS equipment byte, top two bits + 1 == total # of floppies
  185.         test byte [es:0x410],0C0h    
  186.         jz success
  187.         ; ... otherwise pass it to the BIOS
  188. .pass_on:
  189.         pop ax            ; Drop return address
  190.         popad            ; Restore all registers
  191.         pop es
  192.         pop ds
  193.         lss esp,[cs:Stack]    ; Restore the stack
  194.         and dl,80h        ; Clear all but the type bit
  195.         jmp far [cs:OldInt13]
  196.  
  197.  
  198. Invalid:
  199.         pop dx            ; Drop return address
  200. Invalid_jump:
  201.         TRACER 'I'
  202.         mov ah,01h        ; Unsupported function
  203.         jmp short Done
  204.  
  205. GetDriveType:
  206.         test byte [DriveNo],80h
  207.         mov bl,02h        ; Type 02h = floppy with changeline
  208.         jz .floppy
  209.         ; Hard disks only...
  210.         inc bx            ; Type = 03h
  211.         mov dx,[DiskSize]    ; Return the disk size in sectors
  212.         mov P_DX,dx
  213.         mov cx,[DiskSize+2]
  214.         mov P_CX,cx
  215. .floppy:
  216.         mov P_AH,bl        ; 02h floppy, 03h hard disk
  217.         pop ax            ; Drop return address
  218.         xor ax,ax        ; Success...
  219.         jmp short DoneWeird    ; But don't stick it into P_AX
  220.  
  221. GetStatus:
  222.         xor ax,ax
  223.         mov es,ax
  224.         mov bx,[StatusPtr]
  225.         mov ah,[bx]        ; Copy last status
  226.         ret
  227.  
  228. ReadMult:
  229.         TRACER 'm'
  230. Read:
  231.         TRACER 'R'
  232.         call setup_regs
  233. do_copy:
  234.         TRACER '<'
  235.         call bcopy
  236.         TRACER '>'
  237.         movzx ax,P_AL        ; AH = 0, AL = transfer count
  238.         ret
  239.  
  240. WriteMult:
  241.         TRACER 'M'
  242. Write:
  243.         TRACER 'W'
  244.         test byte [ConfigFlags],01h
  245.         jnz .readonly
  246.         call setup_regs
  247.         xchg esi,edi        ; Opposite direction of a Read!
  248.         jmp short do_copy
  249. .readonly:    mov ah,03h        ; Write protected medium
  250.         ret
  251.  
  252.         ; Verify integrity; just bounds-check
  253. Seek:
  254. Verify:
  255.         call setup_regs        ; Returns error if appropriate
  256.         ; And fall through to success
  257.  
  258. CheckIfReady:                ; These are always-successful noop functions
  259. Recalibrate:
  260. InitWithParms:
  261. DetectChange:
  262. SetMode:
  263. success:
  264.         xor ax,ax        ; Always successful
  265.         ret
  266.  
  267. GetParms:
  268.         TRACER 'G'
  269.         mov dl,[DriveCnt]    ; Cached data
  270.         mov P_DL,dl
  271.         test byte [DriveNo],80h
  272.         jnz .hd
  273.         mov P_DI,DPT
  274.         mov P_ES,cs
  275.         mov bl,[DriveType]
  276.         mov P_BL,bl
  277. .hd:
  278.         mov ax,[Cylinders]
  279.         dec ax            ; We report the highest #, not the count
  280.         xchg al,ah
  281.         shl al,6
  282.         or al,[Sectors]
  283.         mov P_CX,ax
  284.         mov ax,[Heads]
  285.         dec ax
  286.         mov P_DH,al
  287.  
  288.         ;
  289.         ; Is this MEMDISK installation check?
  290.         ;
  291.         cmp P_HAX,'ME'
  292.         jne .notic
  293.         cmp P_HCX,'MD'
  294.         jne .notic
  295.         cmp P_HDX,'IS'
  296.         jne .notic
  297.         cmp P_HBX,'K?'
  298.         jne .notic
  299.  
  300.         ; MEMDISK installation check...
  301.         mov P_HAX,'!M'
  302.         mov P_HCX,'EM'
  303.         mov P_HDX,'DI'
  304.         mov P_HBX,'SK'
  305.         mov P_ES,cs
  306.         mov P_DI,MemDisk_Info
  307.  
  308. .notic:
  309.         xor ax,ax
  310.         ret
  311.         
  312.         ; Set up registers as for a "Read", and compares against disk size
  313. setup_regs:
  314.  
  315.         ; Convert a CHS address in P_CX/P_DH into an LBA in eax
  316.         ; CH = cyl[7:0]
  317.         ; CL[0:5] = sector (1-based)  CL[7:6] = cyl[9:8]
  318.         ; DH = head
  319.         movzx ecx,P_CX
  320.         movzx ebx,cl        ; Sector number
  321.         and bl,3Fh
  322.         dec ebx            ; Sector number is 1-based
  323.         cmp bx,[Sectors]
  324.         jae .overrun
  325.         movzx edi,P_DH        ; Head number
  326.         movzx eax,word [Heads]
  327.         cmp di,ax
  328.         jae .overrun
  329.         shr cl,6
  330.         xchg cl,ch        ; Now (E)CX <- cylinder number
  331.         mul ecx            ; eax <- Heads*cyl# (edx <- 0)
  332.         add eax,edi
  333.         mul dword [Sectors]
  334.         add eax,ebx
  335.         ; Now eax = LBA, edx = 0
  336.  
  337.         ;
  338.         ; setup_regs continues...
  339.         ;
  340.         ; Note: edi[31:16] and ecx[31:16] = 0 already
  341.         mov di,P_BX        ; Get linear address of target buffer
  342.         mov cx,P_ES
  343.         shl ecx,4
  344.         add edi,ecx        ; EDI = address to fetch to
  345.         movzx ecx,P_AL        ; Sector count
  346.         mov esi,eax
  347.         add eax,ecx        ; LBA of final sector + 1
  348.         shl esi,SECTORSIZE_LG2    ; LBA -> byte offset
  349.         add esi,[DiskBuf]    ; Get address in high memory
  350.         cmp eax,[DiskSize]    ; Check the high mark against limit
  351.         ja .overrun
  352.         shl ecx,SECTORSIZE_LG2-2 ; Convert count to 32-bit words
  353.         ret
  354.  
  355. .overrun:    pop ax            ; Drop setup_regs return address
  356.         mov ax,0200h        ; Missing address mark
  357.         ret            ; Return to Done
  358.  
  359. int15_e820:
  360.         cmp edx,534D4150h    ; "SMAP"
  361.         jne near oldint15
  362.         cmp ecx,20        ; Need 20 bytes
  363.         jb err86
  364.         push ds
  365.         push cs
  366.         pop ds
  367.         and ebx,ebx
  368.         jne .renew
  369.         mov ebx,E820Table
  370. .renew:
  371.         add bx,12        ; Advance to next
  372.         mov eax,[bx-4]        ; Type
  373.         and eax,eax        ; Null type?
  374.         jz .renew        ; If so advance to next
  375.         mov [es:di+16],eax
  376.         mov eax,[bx-12]        ; Start addr (low)
  377.         mov [es:di],eax
  378.         mov ecx,[bx-8]        ; Start addr (high)
  379.         mov [es:di+4],ecx
  380.         mov eax,[bx]        ; End addr (low)
  381.         mov ecx,[bx+4]        ; End addr (high)
  382.         sub eax,[bx-12]        ; Derive the length
  383.         sbb ecx,[bx-8]
  384.         mov [es:di+8],eax    ; Length (low)
  385.         mov [es:di+12],ecx    ; Length (high)
  386.         cmp dword [bx+8],-1    ; Type of next = end?
  387.         jne .notdone
  388.         xor ebx,ebx        ; Done with table
  389. .notdone:
  390.         mov eax,edx        ; "SMAP"
  391.         pop ds
  392.         mov ecx,20        ; Bytes loaded
  393. int15_success:
  394.         mov byte [bp+6], 02h    ; Clear CF
  395.         pop bp
  396.         iret
  397.  
  398. err86:
  399.         mov byte [bp+6], 03h    ; Set CF
  400.         mov ah,86h
  401.         pop bp
  402.         iret
  403.  
  404. Int15Start:
  405.         push bp
  406.         mov bp,sp
  407.         cmp ax,0E820h
  408.         je near int15_e820
  409.         cmp ax,0E801h
  410.         je int15_e801
  411.         cmp ax,0E881h
  412.         je int15_e881
  413.         cmp ah,88h
  414.         je int15_88
  415. oldint15:    pop bp
  416.         jmp far [cs:OldInt15]
  417.         
  418. int15_e801:
  419.         mov ax,[cs:Mem1MB]
  420.         mov cx,ax
  421.         mov bx,[cs:Mem16MB]
  422.         mov dx,bx
  423.         jmp short int15_success
  424.  
  425. int15_e881:
  426.         mov eax,[cs:Mem1MB]
  427.         mov ecx,eax
  428.         mov ebx,[cs:Mem16MB]
  429.         mov edx,ebx
  430.         jmp short int15_success
  431.  
  432. int15_88:
  433.         mov ax,[cs:MemInt1588]
  434.         jmp short int15_success
  435.  
  436. ;
  437. ; Routine to copy in/out of high memory
  438. ; esi = linear source address
  439. ; edi = linear target address
  440. ; ecx = 32-bit word count 
  441. ;
  442. ; Assumes cs = ds = es
  443. ;
  444. bcopy:
  445.         push eax
  446.         push ebx
  447.         push edx
  448.         push ebp
  449.  
  450.         test byte [ConfigFlags],02h
  451.         jz .anymode
  452.  
  453.         smsw ax            ; Unprivileged!
  454.         test al,01h
  455.         jnz .protmode
  456.  
  457. .realmode:
  458.         TRACER 'r'
  459.         ; We're in real mode, do it outselves
  460.  
  461.         pushfd
  462.         push ds
  463.         push es
  464.  
  465.         cli
  466.         cld
  467.  
  468.         xor ebx,ebx
  469.         mov bx,cs
  470.         shl ebx,4
  471.         lea edx,[Shaker+ebx]
  472.         mov [Shaker+2],edx
  473.  
  474.         ; Test to see if A20 is enabled or not
  475.         xor ax,ax
  476.         mov ds,ax
  477.         dec ax
  478.         mov es,ax
  479.  
  480.         mov ax,[0]
  481.         mov bx,ax
  482.         xor bx,[es:10h]
  483.         not ax
  484.         mov [0],ax
  485.         mov dx,ax
  486.         xor dx,[es:10h]
  487.         not ax
  488.         mov [0],ax
  489.  
  490.         or dx,bx
  491.         jnz .skip_a20e
  492.  
  493.         mov ax,2401h        ; Enable A20
  494.         int 15h
  495. .skip_a20e:
  496.  
  497.         lgdt [cs:Shaker]
  498.         mov eax,cr0
  499.         or al,01h
  500.         mov cr0,eax
  501.  
  502.         mov bx,8
  503.         mov ds,bx
  504.         mov es,bx
  505.  
  506.         a32 rep movsd
  507.  
  508.         add bx,bx        ; BX <- 16
  509.         mov ds,bx
  510.         mov es,bx
  511.  
  512.         and al,~01h
  513.         mov cr0,eax
  514.  
  515.         pop es
  516.         pop ds
  517.  
  518.         and dx,dx
  519.         jnz .skip_a20d
  520.         mov ax,2400h        ; Disable A20
  521.         int 15h
  522. .skip_a20d:
  523.         popfd
  524.         jmp .done
  525.  
  526. .protmode:
  527.         TRACER 'p'
  528. .anymode:
  529.  
  530. .copy_loop:
  531.         push esi
  532.         push edi
  533.         push ecx
  534.         cmp ecx,4000h
  535.         jna .safe_size
  536.         mov ecx,4000h
  537. .safe_size:
  538.         push ecx    ; Transfer size this cycle
  539.         mov eax, esi
  540.         mov [Mover_src1], si
  541.         shr eax, 16
  542.         mov [Mover_src1+2], al
  543.         mov [Mover_src2], ah
  544.         mov eax, edi
  545.         mov [Mover_dst1], di
  546.         shr eax, 16
  547.         mov [Mover_dst1+2], al
  548.         mov [Mover_dst2], ah
  549.         mov si,Mover
  550.         mov ah, 87h
  551.         shl cx,1    ; Convert to 16-bit words
  552.         int 15h
  553.         cli        ; Some BIOSes enable interrupts on INT 15h
  554.         pop eax        ; Transfer size this cycle
  555.         pop ecx
  556.         pop edi
  557.         pop esi
  558.         jc .error
  559.         lea esi,[esi+4*eax]
  560.         lea edi,[edi+4*eax]
  561.         sub ecx, eax
  562.         jnz .copy_loop
  563.         ; CF = 0
  564. .error:
  565. .done:
  566.         pop ebp
  567.         pop edx
  568.         pop ebx
  569.         pop eax
  570.         ret
  571.  
  572. %ifdef DEBUG_TRACERS
  573. debug_tracer:    pushad
  574.         pushfd
  575.         mov bp,sp
  576.         mov bx,[bp+9*4]
  577.         mov al,[cs:bx]
  578.         inc word [bp+9*4]
  579.         mov ah,0Eh
  580.         mov bx,7
  581.         int 10h
  582.         popfd
  583.         popad
  584.         ret
  585. %endif
  586.  
  587.         section .data
  588.         alignb 2
  589. Int13Funcs    dw Reset        ; 00h - RESET
  590.         dw GetStatus        ; 01h - GET STATUS
  591.         dw Read            ; 02h - READ
  592.         dw Write        ; 03h - WRITE
  593.         dw Verify        ; 04h - VERIFY
  594.         dw Invalid        ; 05h - FORMAT TRACK
  595.         dw Invalid        ; 06h - FORMAT TRACK AND SET BAD FLAGS
  596.         dw Invalid        ; 07h - FORMAT DRIVE AT TRACK
  597.         dw GetParms        ; 08h - GET PARAMETERS
  598.         dw InitWithParms    ; 09h - INITIALIZE CONTROLLER WITH DRIVE PARAMETERS
  599.         dw Invalid        ; 0Ah
  600.         dw Invalid        ; 0Bh
  601.         dw Seek            ; 0Ch - SEEK TO CYLINDER
  602.         dw Reset        ; 0Dh - RESET HARD DISKS
  603.         dw Invalid        ; 0Eh
  604.         dw Invalid        ; 0Fh
  605.         dw CheckIfReady        ; 10h - CHECK IF READY
  606.         dw Recalibrate        ; 11h - RECALIBRATE
  607.         dw Invalid        ; 12h
  608.         dw Invalid        ; 13h
  609.         dw Invalid        ; 14h
  610.         dw GetDriveType        ; 15h - GET DRIVE TYPE
  611.         dw DetectChange        ; 16h - DETECT DRIVE CHANGE
  612. %if 0
  613.         dw Invalid        ; 17h
  614.         dw Invalid        ; 18h
  615.         dw Invalid        ; 19h
  616.         dw Invalid        ; 1Ah
  617.         dw Invalid        ; 1Bh
  618.         dw Invalid        ; 1Ch
  619.         dw Invalid        ; 1Dh
  620.         dw Invalid        ; 1Eh
  621.         dw Invalid        ; 1Fh
  622.         dw Invalid        ; 20h
  623.         dw ReadMult        ; 21h - READ MULTIPLE
  624.         dw WriteMult        ; 22h - WRITE MULTIPLE
  625.         dw SetMode        ; 23h - SET CONTROLLER FEATURES
  626.         dw SetMode        ; 24h - SET MULTIPLE MODE
  627.         dw Invalid        ; 25h - IDENTIFY DRIVE
  628.         dw Invalid        ; 26h
  629.         dw Invalid        ; 27h
  630.         dw Invalid        ; 28h
  631.         dw Invalid        ; 29h
  632.         dw Invalid        ; 2Ah
  633.         dw Invalid        ; 2Bh
  634.         dw Invalid        ; 2Ch
  635.         dw Invalid        ; 2Dh
  636.         dw Invalid        ; 2Eh
  637.         dw Invalid        ; 2Fh
  638.         dw Invalid        ; 30h
  639.         dw Invalid        ; 31h
  640.         dw Invalid        ; 32h
  641.         dw Invalid        ; 33h
  642.         dw Invalid        ; 34h
  643.         dw Invalid        ; 35h
  644.         dw Invalid        ; 36h
  645.         dw Invalid        ; 37h
  646.         dw Invalid        ; 38h
  647.         dw Invalid        ; 39h
  648.         dw Invalid        ; 3Ah
  649.         dw Invalid        ; 3Bh
  650.         dw Invalid        ; 3Ch
  651.         dw Invalid        ; 3Dh
  652.         dw Invalid        ; 3Eh
  653.         dw Invalid        ; 3Fh
  654.         dw Invalid        ; 40h
  655.         dw EDDPresence        ; 41h - EDD PRESENCE DETECT
  656.         dw EDDRead        ; 42h - EDD READ
  657.         dw EDDWrite        ; 43h - EDD WRITE
  658.         dw EDDVerify        ; 44h - EDD VERIFY
  659.         dw Invalid        ; 45h - EDD LOCK/UNLOCK MEDIA
  660.         dw Invalid        ; 46h - EDD EJECT
  661.         dw EDDSeek        ; 47h - EDD SEEK
  662.         dw EDDGetParms        ; 48h - EDD GET PARAMETERS
  663. %endif
  664.  
  665. Int13FuncsEnd    equ $
  666. Int13FuncsMax    equ (Int13FuncsEnd-Int13Funcs) >> 1
  667.  
  668.         alignb 8, db 0
  669. Shaker        dw ShakerEnd-$
  670.         dd 0            ; Pointer to self
  671.         dw 0
  672.  
  673. Shaker_DS:    dd 0x0000ffff
  674.         dd 0x008f9300
  675.  
  676. Shaker_RMDS:    dd 0x0000ffff
  677.         dd 0x00009300
  678.  
  679. ShakerEnd    equ $
  680.  
  681.         alignb 8, db 0
  682.  
  683.  
  684. Mover        dd 0, 0, 0, 0        ; Must be zero
  685.         dw 0ffffh        ; 64 K segment size
  686. Mover_src1:    db 0, 0, 0        ; Low 24 bits of source addy
  687.         db 93h            ; Access rights
  688.         db 00h            ; Extended access rights
  689. Mover_src2:    db 0            ; High 8 bits of source addy
  690.         dw 0ffffh        ; 64 K segment size
  691. Mover_dst1:    db 0, 0, 0        ; Low 24 bits of target addy
  692.         db 93h            ; Access rights
  693.         db 00h            ; Extended access rights
  694. Mover_dst2:    db 0            ; High 8 bits of source addy
  695. Mover_dummy2:    dd 0, 0, 0, 0        ; More space for the BIOS
  696.  
  697.         alignb 4, db 0
  698. MemDisk_Info    equ $            ; Pointed to by installation check
  699. MDI_Bytes    dw 27            ; Total bytes in MDI structure
  700. MDI_Version    db VER_MINOR, VER_MAJOR    ; MEMDISK version
  701.  
  702. PatchArea    equ $            ; This gets filled in by the installer
  703.  
  704. DiskBuf        dd 0            ; Linear address of high memory disk
  705. DiskSize    dd 0            ; Size of disk in blocks
  706. CommandLine    dw 0, 0            ; Far pointer to saved command line
  707.  
  708. OldInt13    dd 0            ; INT 13h in chain
  709. OldInt15    dd 0            ; INT 15h in chain
  710.  
  711. OldDosMem    dw 0            ; Old position of DOS mem end
  712. BootLoaderID    db 0            ; Boot loader ID from header
  713. ; ---- MDI structure ends here ---
  714.         db 0, 0, 0        ; pad
  715.  
  716. MemInt1588    dw 0            ; 1MB-65MB memory amount (1K)
  717.  
  718. Cylinders    dw 0            ; Cylinder count
  719. Heads        dw 0            ; Head count
  720. Sectors        dd 0            ; Sector count (zero-extended)
  721.  
  722. Mem1MB        dd 0            ; 1MB-16MB memory amount (1K)
  723. Mem16MB        dd 0            ; 16MB-4G memory amount (64K)
  724.  
  725. DriveNo        db 0            ; Our drive number
  726. DriveType    db 0            ; Our drive type (floppies)
  727. DriveCnt    db 0            ; Drive count (from the BIOS)
  728.  
  729. ConfigFlags    db 0            ; Bit 0 - readonly
  730.  
  731. MyStack        dw 0            ; Offset of stack
  732. StatusPtr    dw 0            ; Where to save status (zeroseg ptr)
  733.  
  734. DPT        times 16 db 0        ; BIOS parameter table pointer (floppies)
  735.  
  736.         ; End patch area
  737.  
  738. Stack        dd 0            ; Saved SS:ESP on invocation
  739.         dw 0
  740. SavedAX        dw 0            ; AX saved on invocation
  741.  
  742.         alignb 4, db 0        ; We *MUST* end on a dword boundary
  743.  
  744. E820Table    equ $            ; The installer loads the E820 table here
  745. TotalSize    equ $            ; End pointer
  746.